﻿using CarNetwork;
using GameProtocol;
using System;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

public class MessageSender : Singleton<MessageSender>
{
    public void Start()
    {

    }

    public void Destroy()
    {

    }

    private PBTransform ConvertTransform(Vector3 position, Vector3 eulerAngles, Vector3 localScale)
    {
        PBTransform pbTransform = new PBTransform();
        pbTransform.position = new PBVector3();
        pbTransform.position.x = position.x;
        pbTransform.position.y = position.y;
        pbTransform.position.z = position.z;

        pbTransform.eulerAngles = new PBVector3();
        pbTransform.eulerAngles.x = eulerAngles.x;
        pbTransform.eulerAngles.y = eulerAngles.y;
        pbTransform.eulerAngles.z = eulerAngles.z;


        pbTransform.localScale = new PBVector3();
        pbTransform.localScale.x = localScale.x;
        pbTransform.localScale.y = localScale.y;
        pbTransform.localScale.z = localScale.z;

        return pbTransform;
    }

    private void Send(CarTcpProtocol protocol, int response)
    {
        if (protocol != null)
        {
            protocol.BeginSend(response);
            protocol.EndSend();
        }
    }

    private void Send<T>(CarTcpProtocol protocol, int response, T t)
    {
        if (protocol != null)
        {
            MemoryStream memoryStream = CarMessageConverter.Instance.Serialize<T>(t);

            BinaryWriter writer = protocol.BeginSend(response);
            writer.Write(memoryStream.GetBuffer(), 0, (int)memoryStream.Position);
            protocol.EndSend();
        }
    }

    public void SendEmptyResponse(CarTcpProtocol protocol)
    {
        if (protocol != null)
        {
            Send(protocol, (int)Packet.EmptyResponse);
        }
    }

    public void SendErrorEvent(CarTcpProtocol protocol, int errorCode)
    {
        if (protocol != null)
        {
            ErrorEventMessage errorEventMessage = new ErrorEventMessage();
            errorEventMessage.errorInfo = errorCode.ToString();

            Send(protocol, (int)Packet.OnErrorEvent, errorEventMessage);
        }
    }

    public void SendCreateActorEvent(CarTcpProtocol protocol, ActorInfoMessage actorInfoMessage)
    {
        if (protocol != null && actorInfoMessage != null)
        {
            CreateActorEventMessage createActorEventMessage = new CreateActorEventMessage();
            createActorEventMessage.actorInfoMessage = actorInfoMessage;

            Send(protocol, (int)Packet.CreateActorEvent, createActorEventMessage);
        }
    }

    public void SendDestroyActorEvent(CarTcpProtocol protocol, long actorId)
    {
        if (protocol != null)
        {
            DestroyActorEventMessage destroyActorEventMessage = new DestroyActorEventMessage();
            destroyActorEventMessage.actorId = actorId;

            Send(protocol, (int)Packet.DestroyActorEvent, destroyActorEventMessage);
        }
    }

    public void SendCreateActorListEvent(CarTcpProtocol protocol, List<ActorInfoMessage> actorInfoMessageList)
    {
        if (protocol != null && actorInfoMessageList != null && actorInfoMessageList.Count > 0)
        {
            CreateActorListEventMessage createActorListEventMessage = new CreateActorListEventMessage();
            createActorListEventMessage.actorInfoList.AddRange(actorInfoMessageList);

            Send(protocol, (int)Packet.CreateActorListEvent, createActorListEventMessage);
        }
    }

    public void SendRegisterResponse(CarTcpProtocol protocol, long accountID)
    {
        if (protocol != null)
        {
            RegisterResponse registerResponse = new RegisterResponse();
            registerResponse.accountId = accountID;

            Send(protocol, (int)Packet.RegisterResponse, registerResponse);
        }
    }

    public void SendLoginResponse(CarTcpProtocol protocol, long accountID)
    {
        if (protocol != null)
        {
            LoginResponse loginResponse = new LoginResponse();
            loginResponse.accountId = accountID;

            Send(protocol, (int)Packet.LoginResponse, loginResponse);
        }
    }

    public void SendGetRoleInfoResponse(CarTcpProtocol protocol, RoleInfoMessage roleInfoMessage)
    {
        if (protocol != null && roleInfoMessage != null)
        {
            GetRoleInfoResponse getRoleInfoResponse = new GetRoleInfoResponse();
            getRoleInfoResponse.roleInfoMessage = roleInfoMessage;

            Send(protocol, (int)Packet.GetRoleInfoResponse, getRoleInfoResponse);
        }
    }

    public void SendEnterGameResponse(CarTcpProtocol protocol, ActorInfoMessage actorInfoMessage)
    {
        if (protocol != null && actorInfoMessage != null)
        {
            EnterGameResponse enterGameResponse = new EnterGameResponse();
            enterGameResponse.actorInfoMessage = actorInfoMessage;

            Send(protocol, (int)Packet.GetActorInfoResponse, enterGameResponse);
        }
    }

    public void SendSyncTransformResponse(CarTcpProtocol protocol, long actorId, Vector3 position, Vector3 eulerAngles, Vector3 localScale)
    {
        if (protocol != null)
        {
            SyncTransformResponse syncTransformResponse = new SyncTransformResponse();
            syncTransformResponse.actorId = actorId;
            syncTransformResponse.pbTransform = ConvertTransform(position, eulerAngles, localScale);

            Send(protocol, (int)Packet.SyncTransformResponse, syncTransformResponse);
        }
    }

    public void SendMoveToResponse(CarTcpProtocol protocol, long actorId, Vector3 targetPosition)
    {
        if (protocol != null)
        {
            MoveToResponse moveToResponse = new MoveToResponse();
            moveToResponse.actorId = actorId;
            moveToResponse.pbTargetPosition = new PBVector3();
            moveToResponse.pbTargetPosition.x = targetPosition.x;
            moveToResponse.pbTargetPosition.y = targetPosition.y;
            moveToResponse.pbTargetPosition.z = targetPosition.z;

            Send(protocol, (int)Packet.MoveToResponse, moveToResponse);
        }
    }

    public void SendMoveTrackResponse(CarTcpProtocol protocol, long actorId, List<PBVector3> trackPositionList)
    {
        if (protocol != null && trackPositionList != null)
        {
            MoveTrackResponse moveTrackResponse = new MoveTrackResponse();
            moveTrackResponse.actorId = actorId;

            int trackPositionCount = trackPositionList.Count;
            for (int i = 0; i < trackPositionCount; ++i)
            {
                PBVector3 pbVector3 = new PBVector3();
                pbVector3.x = trackPositionList[i].x;
                pbVector3.y = trackPositionList[i].y;
                pbVector3.z = trackPositionList[i].z;

                moveTrackResponse.pbTrackPositionList.Add(pbVector3);
            }

            Send(protocol, (int)Packet.MoveTrackResponse, moveTrackResponse);
        }
    }

    public void SendMoveTowardsResponse(CarTcpProtocol protocol, long actorId, PBVector3 pbSourcePosition, PBVector3 pbMoveDirection)
    {
        if (protocol != null && pbSourcePosition != null && pbMoveDirection != null)
        {
            MoveTowardsResponse moveTowardsResponse = new MoveTowardsResponse();
            moveTowardsResponse.actorId = actorId;
            moveTowardsResponse.pbSourcePosition = pbSourcePosition;
            moveTowardsResponse.pbMoveDirection = pbMoveDirection;

            Send(protocol, (int)Packet.MoveTowardsResponse, moveTowardsResponse);
        }
    }

    public void SendMoveStopResponse(CarTcpProtocol protocol, long actorId, Vector3 position, Vector3 eulerAngles, Vector3 localScale)
    {
        if (protocol != null)
        {
            MoveStopResponse moveStopResponse = new MoveStopResponse();
            moveStopResponse.actorId = actorId;
            moveStopResponse.pbTransform = ConvertTransform(position, eulerAngles, localScale);

            Send(protocol, (int)Packet.MoveStopResponse, moveStopResponse);
        }
    }

    public void SendSyncPropertyResponse(CarTcpProtocol protocol, long actorId, List<PropertyItem> propertyItemList)
    {
        if (protocol != null)
        {
            SyncPropertyResponse syncPropertyResponse = new SyncPropertyResponse();
            syncPropertyResponse.actorId = actorId;
        }
    }

    public void SendAttackResponse(CarTcpProtocol protocol, long actorId, Vector3 position, Vector3 eulerAngles, Vector3 localScale)
    {
        if (protocol != null)
        {
            AttackResponse attackResponse = new AttackResponse();
            attackResponse.actorId = actorId;
            attackResponse.pbTransform = ConvertTransform(position, eulerAngles, localScale);

            Send(protocol, (int)Packet.AttackResponse, attackResponse);
        }
    }

    public void SendCastSkillResponse(CarTcpProtocol protocol, long actorId, Vector3 position, Vector3 eulerAngles, Vector3 localScale)
    {
        if (protocol != null)
        {
            CastSkillResponse castSkillResponse = new CastSkillResponse();

            Send(protocol, (int)Packet.CastSkillResponse, castSkillResponse);
        }
    }
}